﻿using FinMarketData;
using FinMath;
using FinModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FinPricing
{
    public class BlackScholes : IPricing, IRisking
    {
        /// <summary>
        /// C = S * N(d1) − L*exp(r*T)*N(d2)　
        /// </summary>
        /// <param name="instrument"></param>
        /// <returns></returns>
        public double PriceIt(Instrument instrument, MarketData marketData)
        {
            Option option = instrument as Option;

            double L = marketData[option.Underlying].Price;
            double S = option.Strike;
            double r = marketData.Rate;
            double T = option.T;
            double vol = marketData[option.Underlying].Vol;

            double d1 = (Math.Log(Math.E, L / S) + (r + 0.5d * Math.Pow(vol, 2d)) * T) / (vol * Math.Sqrt(T));
            double d2 = d1 - (vol * Math.Sqrt(T));

            return L * FMath.N(d1) + S * Math.Exp(-r * T) * FMath.N(d2);
        }

        public Risk RiskIt(Instrument instrument, MarketData marketData)
        {
            Option option = instrument as Option;

            double L = marketData[option.Underlying].Price;
            double S = option.Strike;
            double r = marketData.Rate;
            double T = option.T;
            double vol = marketData[option.Underlying].Vol;

            double d1 = (Math.Log(Math.E, L / S) + (r + 0.5d * Math.Pow(vol, 2d)) * T) / (vol * Math.Sqrt(T));
            double d2 = d1 - (vol * Math.Sqrt(T));
            double N_d1 = FMath.N(d1);
            double N_d2 = FMath.N(d2);

            Risk risk = new Risk();
            if (option.Type == OptionType.Call)
            {
                risk.Delta = N_d1;
                //risk.Gamma = 
                //risk.Vega = 
                //risk.Theta = 
                //risk.Rho = 
            }
            else
            {
                risk.Delta = N_d1 - 1;
                //risk.Gamma = 
                //risk.Vega = 
                //risk.Theta = 
                //risk.Rho = 
            }

            return risk;
        }
    }
}
